package architecture;

//_EX_ForwardingUnit
public class _EX_ForwardingUnit{
	MyInt EX_MEM_RegisterRd;
	MyInt EX_MEM_RegWrite;
	MyInt MEM_WB_RegisterRd;
	MyInt MEM_WB_RegWrite;
	MyInt ID_EX_RegisterRt;
	MyInt ID_EX_RegisterRs;
	MyInt MEM_WB_MemToReg;
	
	MyInt forwardA;
	MyInt forwardB;
	
	boolean forwardingFailureA;
	boolean forwardingFailureB;
	
	MyBoolean ex_is_forwarding;
	void setforwardAB(){
		forwardA.i=0;
		forwardB.i=0;
		
		forwardingFailureA=false;
		forwardingFailureB=false;
		
		int total_forwardA=0;
		int total_forwardB=0;
		
		int forwardAChanged=0;
		int forwardBChanged=0;
		
		if(MEM_WB_RegWrite.i==1
				&&MEM_WB_RegisterRd.i==ID_EX_RegisterRs.i
				&&(EX_MEM_RegisterRd.i!=ID_EX_RegisterRs.i
						||EX_MEM_RegWrite.i==0)){
			total_forwardA=1;
			forwardAChanged++;
		}
		if(MEM_WB_RegWrite.i==1
				&&MEM_WB_RegisterRd.i==ID_EX_RegisterRt.i
				&&(EX_MEM_RegisterRd.i!=ID_EX_RegisterRt.i
						||EX_MEM_RegWrite.i==0)){
			total_forwardB=1;
			forwardBChanged++;
		}
		if(EX_MEM_RegWrite.i==1
				&&EX_MEM_RegisterRd.i==ID_EX_RegisterRs.i){
			total_forwardA=2;
			forwardAChanged++;
		}
		if(EX_MEM_RegWrite.i==1
				&&EX_MEM_RegisterRd.i==ID_EX_RegisterRt.i){
			total_forwardB=2;
			forwardBChanged++;
		}
		assert(forwardAChanged<=1&&forwardBChanged<=1);
		
		if(total_forwardA==1) {
			if(MEM_WB_MemToReg.i==1){
				forwardA.i=1;
			}
			else forwardA.i=2;
		}
		else if(total_forwardA==2){
			forwardA.i=3;
		}
		
		if(total_forwardB==1) {
			if(MEM_WB_MemToReg.i==1){
				forwardB.i=1;
			}
			else forwardB.i=2;
		}
		else if(total_forwardB==2){
			forwardB.i=3;
		}
	}
	void clockEvent(){
		setforwardAB();
		if(!ex_is_forwarding.b){
			if(forwardA.i!=0){
				forwardingFailureA=true;
				forwardA.i=0;
			}
			if(forwardB.i!=0){
				forwardingFailureB=true;
				forwardB.i=0;
			}
		}
	}
	void dump(){
		System.out.println("--------");
		System.out.println("_EX_ForwardingUnit:");
		System.out.println("EX_MEM_RegisterRd:"+EX_MEM_RegisterRd);
		System.out.println("EX_MEM_RegWrite:"+EX_MEM_RegWrite);
		System.out.println("MEM_WB_RegisterRd:"+MEM_WB_RegisterRd);
		System.out.println("MEM_WB_RegWrite:"+MEM_WB_RegWrite);
		System.out.println("ID_EX_RegisterRt:"+ID_EX_RegisterRt);
		System.out.println("ID_EX_RegisterRs:"+ID_EX_RegisterRs);
		System.out.println("MEM_WB_MemToReg:"+MEM_WB_MemToReg);
		System.out.println("forwardA:"+forwardA);
		System.out.println("forwardB:"+forwardB);
		System.out.println("--------");
	}
}